/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package afterubuntu.script;

import afterubuntu.Main;
import afterubuntu.log.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextArea;

/**
 *
 * @author Kermit
 */
public class ExecuteScript implements Runnable{

    private JTextArea console;
    private File scriptFile;

    private String tmpDir;

    private BufferedWriter scriptInput;

    private Process script;

    public ExecuteScript(File scriptFile, JTextArea console) {
        this.console = console;
        this.scriptFile = scriptFile;
        this.tmpDir = "/tmp/afterubuntu";
    }

    public void run() {
        PrintWriter tmpScriptWriter = null;
        BufferedReader scriptReader = null;
        BufferedReader scriptOutput = null;
        try{
            int result;
            print("Starting...\n");

            print("\nCreating temp files...\n");
            File tmpDirScript = new File(tmpDir);
            boolean res;
            if(!tmpDirScript.exists()){
                res = tmpDirScript.mkdir();
                if(!res){
                    print("ERROR creating tmp directory " + tmpDir + "\n");
                    print("EXITING");
                    return;
                }
            }
            Date date = new Date();
            long timestamp = date.getTime();
            File tmpScript = new File(tmpDirScript, scriptFile.getName().substring(0, scriptFile.getName().indexOf(".")) + "_" + timestamp + ".sh");
            res = tmpScript.createNewFile();
            if(!res){
                print("ERROR creating tmp file " + tmpScript.getAbsolutePath() + "\n");
                print("EXITING");
                return;
            }
            File tmpAskPass = new File(tmpDirScript, "afterUbuntuAskPass_" + timestamp + ".sh");
            res = tmpAskPass.createNewFile();
            if(!res){
                print("ERROR creating tmp file " + tmpAskPass.getAbsolutePath() + "\n");
                print("EXITING");
                return;
            }
            PrintWriter tmpAskPassWriter = new PrintWriter(tmpAskPass);
            String appLocation = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
            tmpAskPassWriter.write("#!/bin/bash\n");
            tmpAskPassWriter.write("java -jar " + appLocation + " askpass\n");
            tmpAskPassWriter.flush();
            tmpAskPassWriter.close();
            Process chmodAskPass = Runtime.getRuntime().exec("chmod 744 " + tmpAskPass.getAbsolutePath());
            result = chmodAskPass.waitFor();
            if(result != 0){
                print("ERROR modifing execution permission on " + tmpAskPass.getAbsolutePath() + "\n");
                print("EXITING");
                return;
            }

        
            print("\nConfiguring execution...\n");
            tmpScriptWriter = new PrintWriter(tmpScript);
            scriptReader = new BufferedReader(new FileReader(scriptFile));
            boolean binSlashBash = false;
            String line;
            while((line = scriptReader.readLine()) != null){
                line = line.replaceAll("sudo ", "sudo -A ");
                tmpScriptWriter.write(line + "\n");
                if(!binSlashBash){
                    tmpScriptWriter.write("export SUDO_ASKPASS=" + tmpDirScript + "/afterUbuntuAskPass_" + timestamp + ".sh\n");
                    binSlashBash = true;
                }
            }

            scriptReader.close();
            tmpScriptWriter.flush();
            tmpScriptWriter.close();

            Process chmod = Runtime.getRuntime().exec("chmod 744 " + tmpScript.getAbsolutePath());
            result = chmod.waitFor();
            if(result != 0){
                print("ERROR modifing execution permission on " + tmpScript.getAbsolutePath() + "\n");
                print("EXITING");
                return;
            }
            
            print("\nExecuting script...\n\n");
            ProcessBuilder processBuilder = new ProcessBuilder(tmpScript.getAbsolutePath());
            processBuilder.redirectErrorStream(true);
            script = processBuilder.start();
            scriptOutput = new BufferedReader(new InputStreamReader(script.getInputStream()));
            scriptInput = new BufferedWriter(new OutputStreamWriter(script.getOutputStream()));
            while ((line = scriptOutput.readLine()) != null) {
                print(line + "\n");
            }
            script.waitFor();
            script.destroy();

            print("\nDeleting tmp files...\n");
            Process rm = Runtime.getRuntime().exec("rm -r " + tmpDir);
            result = rm.waitFor();
            if(result != 0){
                print("ERROR deleting tmp files\n");
            }
            print("\nExecution finished");

        } catch (IOException ex) {
            Log.getInstance().log(Log.ERROR, ex.getLocalizedMessage());
        } catch (InterruptedException ex) {
            Log.getInstance().log(Log.ERROR, ex.getLocalizedMessage());
        } catch (URISyntaxException ex){
            Log.getInstance().log(Log.ERROR, ex.getLocalizedMessage());
        } finally {
            if(tmpScriptWriter != null) tmpScriptWriter.close();
            if(scriptReader != null){
                try {
                    scriptReader.close();
                } catch (IOException ex) {
                    Log.getInstance().log(Log.ERROR, ex.getLocalizedMessage());
                }
            }
        }
    }

    private void print(String line){
         console.append(line);     
    }

    public void stop() {
        script.destroy();
    }
}
